package com.hj.calendar.client;

import cn.hutool.core.date.DateUtil;
import com.github.caldav4j.CalDAVConstants;
import com.github.caldav4j.methods.CalDAV4JMethodFactory;
import com.github.caldav4j.methods.HttpCalDAVReportMethod;
import com.github.caldav4j.model.response.CalendarDataProperty;
import com.hj.calendar.domain.constant.SymbolConstant;
import com.hj.calendar.domain.dto.CaldavDdFsDTO;
import com.hj.calendar.domain.model.CaldavModel;
import lombok.extern.slf4j.Slf4j;
import net.fortuna.ical4j.model.ComponentList;
import net.fortuna.ical4j.model.component.VEvent;
import net.fortuna.ical4j.model.property.*;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpResponse;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.client.HttpClient;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.impl.client.HttpClients;
import org.apache.jackrabbit.webdav.DavException;
import org.apache.jackrabbit.webdav.property.DavProperty;

import java.util.Collection;
import java.util.Date;
import java.util.List;

/**
 * @author hj
 * @Date 2023/5/22
 * @Description: Caldav操作客户端
 */
@Slf4j
public class CaldavClient {

    /**
     * 创建 http客户端
     *
     * @param user     用户名
     * @param password 密码
     * @return org.apache.http.client.HttpClient
     */
    public static HttpClient createHttpClient(String user, String password) {
        CredentialsProvider credProvider = new BasicCredentialsProvider();
        credProvider.setCredentials(
                AuthScope.ANY,
                new UsernamePasswordCredentials(user, password));
        return HttpClients.custom().setDefaultCredentialsProvider(credProvider).build();
    }

    /**
     * 创建 方法工厂
     *
     * @return CalDAV4JMethodFactory
     */
    public static CalDAV4JMethodFactory createFactory() {
        return new CalDAV4JMethodFactory();
    }

    /**
     * 日期格式转化为处理 20220424T000000Z
     *
     * @param dto CaldavFsDTO
     */
    public static void handleFsCaldavDate(CaldavDdFsDTO dto) {
        Date startTime = dto.getStartTime();
        Date endTime = dto.getEndTime();
        if (null != startTime) {
            dto.setCaldavStartTime(dateToStr(startTime));
        }
        if (null != endTime) {
            dto.setCaldavEndTime(dateToStr(endTime));
        }
    }

    /**
     * 处理日程数据
     *
     * @param caldavReportMethod HttpCalDAVReportMethod
     * @param response           HttpResponse
     * @param ddCaldavModelList  List<CaldavModel>
     */
    public static void handleCalendar(HttpCalDAVReportMethod caldavReportMethod, HttpResponse response,
                                      List<CaldavModel> ddCaldavModelList) throws DavException {
        Collection<DavProperty> calendars = caldavReportMethod.getDavProperties(response, CalDAVConstants.DNAME_CALENDAR_DATA);
        ComponentList<VEvent> tempList = new ComponentList<>();
        for (DavProperty property : calendars) {
            tempList.addAll(
                    CalendarDataProperty.getCalendarfromProperty(property)
                            .getComponents(net.fortuna.ical4j.model.Component.VEVENT));
        }
        for (VEvent e : tempList) {
            CaldavModel m = new CaldavModel();
            handleCaldavModel(e, m);
            ddCaldavModelList.add(m);
        }
    }

    /**
     * 处理返回的日历数据
     *
     * @param e VEvent
     * @param m CaldavModel
     */
    public static void handleCaldavModel(VEvent e, CaldavModel m) {
        Uid uid = e.getUid();
        m.setUid(uid.getValue());

        DtStart startDate = e.getStartDate();
        m.setStartTime(strToDate(startDate.getValue()));
        DtEnd endDate = e.getEndDate();
        m.setEndTime(strToDate(endDate.getValue()));

        Description description = e.getDescription();
        if (null != description) {
            m.setDescription(description.getValue());
        }
        Summary summary = e.getSummary();
        if (null != summary) {
            m.setSummary(summary.getValue());
        }
        Location location = e.getLocation();
        if (null != location) {
            m.setLocation(location.getValue());
        }
    }

    public static String dateToStr(Date date) {
        String s = DateUtil.format(date, "yyyyMMdd-HHmmss*");
        s = s.replace("-", SymbolConstant.LETTER_T);
        s = s.replace("*", SymbolConstant.LETTER_Z);
        return s;
    }

    public static Date strToDate(String caldavStr) {
        if (StringUtils.isBlank(caldavStr)) {
            return null;
        }
        Date date;
        if (caldavStr.contains(SymbolConstant.LETTER_T)) {
            caldavStr = caldavStr.replace(SymbolConstant.LETTER_T, "-");
            date = DateUtil.parse(caldavStr, "yyyyMMdd-HHmmss");
        } else {
            date = DateUtil.parse(caldavStr, "yyyyMMdd");
        }
        return date;
    }


}
